import React from 'react';
import './-page.scss';
import {observable, observer, computed, action} from 'mobx.collection';
import {DynamicUploadInput, ReactInput, ReactLabel, ReactSelect} from "components/data/react-element";
import {formatClassList} from "auxiliaries/extends/format";
import {DictController} from "api/dict";
import {getRandomString} from "auxiliaries/extends/random";
import {loaded, loading, notify} from "components/state/toast";
import AsyncSelect from "react-select/lib/Async";
import BROWSERTYPE from "auxiliaries/extends/browser-type";


@observer
class ReactHorizonSelect extends React.Component {
    #ReactSelectElement;

    @observable _currentOptions;

    @computed get label() {
        return this._currentOptions?.label;
    }


    onChange(x) {
        this._currentOptions = x;

        this.props.onChange?.(x);
    }

    render() {
        let {
            options,
            label,
            value,
            placeholder
        } = this.props;

        return (

            <div className={"--react-horizon-select"}>
                <ReactLabel label={label}>
                    <div
                        className={"font-size-30 --span-placeholder" + (this.label ? "" : " off")}>{this.label || placeholder}</div>
                    <div className={"right-ico"}/>
                </ReactLabel>
                <ReactSelect ref={_ => this.#ReactSelectElement = _}
                             className={"--react-hidden-select font-size-30"}
                             autoFocus={false}
                             value={value}
                             placeholder={placeholder}
                             onChange={this.onChange.bind(this)}
                             options={options}/>
            </div>
        );
    }
}

class ReactHorizonInput extends React.Component {
    #ReactHorizonElement;

    set value(val) {
        if (this.#ReactHorizonElement) {
            this.#ReactHorizonElement.value = val;
        }
    }

    get value() {
        return this.#ReactHorizonElement?.value;
    }

    render() {
        let {
            label,
            title,
            type,
            className,
            placeholder,
            inputClassName,
            value,
            defaultValue,
            inputProps,
            disabled,
            hasRightIcon,
            readonly,
            onInput,
            onChange,
            onBlur,
            ...rest
        } = this.props;
        let list = formatClassList(className);

        list.push('--react-horizon-input');
        hasRightIcon && list.push('--react-horizon-right');

        return (
            <ReactLabel label={title || label} className={list.join(' ')} {...rest}>
                <ReactInput ref={_ => this.#ReactHorizonElement = _} disabled={disabled} type={type} value={value}
                            onChange={onChange} onInput={onInput} placeholder={placeholder} defaultValue={defaultValue}
                            onBlur={onBlur}
                            className={inputClassName} readonly={readonly} {...inputProps}/>
                {this.props.children}
                {
                    hasRightIcon ?
                        <div className={"right-ico"}/>
                        : null
                }
            </ReactLabel>
        );
    }
}

@observer
class SelectScaleUnit extends React.Component {
    #SelectID = 'ELEMENTSELECT-' + getRandomString();

    @observable value;
    @observable scaleText = '';
    @observable text = '';
    @observable scaleList = [];

    @action
    onSelectYen(e) {
        this.value = e.currentTarget.value;
        this.scaleText = this.scaleList.find(x => x.Id === this.value)?.Name || this.scaleList[0]?.Name;
    }

    @action
    onChange(e) {
        this.text = e.currentTarget.value;
        this.props.onChange?.(this);
    }

    @action
    async componentDidMount() {
        let {DATA, STATUS, DETAILS, MESSAGE} = await DictController.GetScaleUnit();
        if (STATUS === 0) {
            this.scaleList = DATA;
            this.value = this.value || DATA[0]?.Id;
            this.scaleText = DATA.find(x => x.Id === this.value)?.Name;

            this.onChange({currentTarget: {value: this.value}});
        } else {
            notify(DETAILS || MESSAGE);
        }

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value) {
            this.text = nextProps.value.text || this.text;
            this.value = nextProps.value.value || this.value;
            this.scaleText = this.scaleList?.find(x => x.Id === this.value)?.Name;
        }
    }

    render() {
        return (
            <ReactHorizonInput label={this.props.label || this.props.title} placeholder={this.props.placeholder}
                               className={this.props.className}
                               hasRightIcon={true}
                               value={this.text}
                               onChange={this.onChange.bind(this)}
                               inputProps={{
                                   type: "number"
                               }}
                               disabled={this.props.disabled}
                               inputClassName={"font-size-30"}>
                <select disabled={this.props.disabled} id={this.#SelectID} onChange={this.onSelectYen.bind(this)}
                        value={this.value}
                        className={"unit font-size-30"}>
                    {
                        this.scaleList.map(x => (
                            <option key={x.Id} value={x.Id}>{x.Name}</option>
                        ))
                    }
                </select>
            </ReactHorizonInput>
        );
    }
}

@observer
class ReactIDCardUpload extends React.Component {
    @observable ImageUrl;

    async onUpload(e) {
        let file = e.files?.[0];

        let ok = await this.props?.onUpload?.(e.files);
        loaded();

        if (ok === false) {
            return;
        }

        if (file) {
            this.ImageUrl = file;
        }
    }

    onBeforeUpload() {
        loading('正在上传');
    }

    render() {
        let {
            title,
            className,
            details,
            disabled,
            url,
            onUpload,
            ...props
        } = this.props;
        let resultClassName = ["--react-idcard-upload",].concat(formatClassList(className)).join(' ');

        return (
            <div className={resultClassName} {...props}>
                <div className="--title">{title}</div>
                <div className="idcard-upload-container">
                    <div className="--upload-icon-group font-size-28">
                        <DynamicUploadInput disabled={disabled} type="file" accept="image/*" multiple=""
                                            onBeforeUpload={this.onBeforeUpload.bind(this)}
                                            // upload={!!BROWSERTYPE.isWeChat}
                                            onChange={this.onUpload.bind(this)}/>
                        <div className="add-icon-2 -upload-margin-bottom"/>
                        {
                            this.ImageUrl || url ? null :
                                details?.map(x => (
                                    <div key={x}>{x}</div>
                                ))
                        }
                        <div className="--img" style={{
                            backgroundImage: `url("${this.ImageUrl || url}")`
                        }}/>
                    </div>
                </div>
            </div>
        );
    }
}

@observer
class HorizonMultiSelect extends React.Component {
    render() {
        return (
            <div className={["react-horizon-multi-select-container"]
                .concat(formatClassList(this.props.className)).join(' ')}>
                <div className="multi-select-container-size">
                    <div className="multi-select-title">{this.props.title}</div>
                    <AsyncSelect className='react-select-container'
                                 isSearchable={false}
                                 classNamePrefix="react-select"
                                 closeMenuOnSelect={false}
                                 onChange={this.props.onChange}
                                 cacheOptions
                                 isHidden
                                 defaultOptions
                                 placeholder={this.props.placeholder}
                                 noOptionsMessage={() => this.props.noOptionsMessage || '暂无选项'}
                                 isMulti
                                 blurInputOnSelect
                                 loadOptions={() => this.props.options}
                    >
                        <div>123</div>
                    </AsyncSelect>
                    <div className="right-ico"/>
                </div>
            </div>
        );
    }
}

export {
    ReactHorizonSelect,
    ReactHorizonInput,
    SelectScaleUnit,
    ReactIDCardUpload,
    HorizonMultiSelect
};